import json

from model import *
from flask import render_template, request
from util import *
from auth_decorator import role_authorization

# 配置 CORS，允许所有域名跨域
@app.after_request
def after_request(response):
    response.headers.add('Access-Control-Allow-Origin', '*')
    response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization')
    response.headers.add('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
    return response


@app.route('/api')
def api():
    return render_template('api-doc.html')


@app.route('/user/login', methods=['GET', 'POST'])
def login():
    user_id = request.args.get('userId')
    password = request.args.get('password')

    # 尝试管理员登录
    admin = Admin.query.filter_by(admin_id=user_id).first()
    if admin and admin.verify_password(password):
        payload = {"adminId": user_id, "role": Role.MANAGER}
        token = PWT.get_token(payload)
        return DataResult.success_by_message("登录成功", {"token": token}).to_dict()

    # 尝试学生登录
    student = Student.query.filter_by(card_id=user_id).first()
    if student and student.verify_password(password):
        payload = {"cardId": user_id, "role": Role.USER}
        token = PWT.get_token(payload)
        return DataResult.success_by_message("登录成功", {"token": token}).to_dict()

    return DataResult.err_by_err_code('LOGIN_ERROR').to_dict()

@app.route('/user/student', methods=['GET'])
@role_authorization(required_role=Role.USER)
def get_student():
    token = request.args.get("token")
    decoded = PWT.verify(token)
    card_id = request.args.get('cardId')
    role = decoded.get('role')

    if role == Role.MANAGER:
        if card_id:
            student = Student.query.filter_by(card_id=card_id).first()
            if student:
                student.password = "***"
                return DataResult.success_by_datas(student.to_dict()).to_dict()
        students = Student.query.all()
        for student in students:
            student.password = "***"
        return DataResult.success_by_datas([s.to_dict() for s in students]).to_dict()

    if role == Role.USER and decoded.get('cardId') == card_id:
        student = Student.query.filter_by(card_id=card_id).first()
        if student:
            student.password = "***"
            return DataResult.success_by_datas(student.to_dict()).to_dict()

    return DataResult.err_by_err_code('PERMISSION_DENY').to_dict()

@app.route('/user/student', methods=['PUT'])
@role_authorization(required_role=Role.MANAGER)
def update_student():
    data = json.loads(request.get_data().decode('utf-8'))
    card_id = data.get('cardId')
    if not card_id:
        return DataResult.err().to_dict()

    student = Student.query.filter_by(card_id=card_id).first()
    if student:
        for key, value in data.items():
            setattr(student, key, value)
        db.session.commit()
        return DataResult.success_by_message("更新学生信息成功").to_dict()

    return DataResult.err().to_dict()

@app.route('/user/student', methods=['POST'])
@role_authorization(required_role=Role.MANAGER)
def add_student():
    data = json.loads(request.get_data().decode('utf-8'))
    print(data)
    student = Student(**data)
    print(student.to_dict())
    db.session.add(student)
    db.session.commit()
    return DataResult.success_by_message("新增学生信息成功").to_dict()

@app.route('/user/student', methods=['DELETE'])
@role_authorization(required_role=Role.MANAGER)
def delete_student():
    card_id = request.args.get('cardId')
    if not card_id:
        return DataResult.err().to_dict()

    student = Student.query.filter_by(card_id=card_id).first()
    if student:
        db.session.delete(student)
        db.session.commit()
        return DataResult.success_by_message("删除学生信息成功").to_dict()

    return DataResult.err().to_dict()

@app.route('/user/admin', methods=['GET'])
@role_authorization(required_role=Role.MANAGER)
def get_admin():
    token = request.args.get("token")
    decoded = PWT.verify(token)
    admin_id = request.args.get('adminId') or decoded.get('adminId')
    if admin_id != decoded.get('adminId'):
        return DataResult.err_by_err_code('PERMISSION_DENY').to_dict()

    admin = Admin.query.filter_by(admin_id=admin_id).first()
    if admin:
        admin.password = "***"
        return DataResult.success_by_datas(admin.to_dict()).to_dict()

    return DataResult.err_by_err_code('NOT_FOUND').to_dict()


# 查询书籍
@app.route('/book', methods=['GET'])
def search_book():
    book_name = request.args.get('bookName')
    isbn = request.args.get('isbn')
    author = request.args.get('author')
    press = request.args.get('press')
    class_name = request.args.get('className')

    # 构造查询条件
    query = Book.query
    if book_name:
        query = query.filter(Book.book_name.like(f"%{book_name}%"))
    if isbn:
        query = query.filter(Book.isbn == isbn)
    if author:
        query = query.filter(Book.author.like(f"%{author}%"))
    if press:
        query = query.filter(Book.press.like(f"%{press}%"))
    if class_name:
        query = query.filter(Book.class_name.like(f"%{class_name}%"))

    books = query.all()
    if not books:
        return DataResult.success_by_datas([]).to_dict()

    books_data = [book.to_dict() for book in books]
    return DataResult.success_by_datas(books_data).to_dict()

# 新增书籍
@app.route('/book', methods=['POST'])
def add_book():
    data = json.loads(request.get_data().decode('utf-8'))
    book = Book(
        isbn=data.get('isbn'),
        book_name=data.get('bookName'),
        author=data.get('author'),
        press=data.get('press'),
        class_name=data.get('className')
    )
    db.session.add(book)
    try:
        db.session.commit()
        return DataResult.succ().to_dict()
    except Exception as e:
        db.session.rollback()
        return DataResult.err().to_dict()

# 更新书籍
@app.route('/book', methods=['PUT'])
def update_book():
    data = json.loads(request.get_data().decode('utf-8'))
    isbn = data.get('isbn')
    if not isbn:
        return DataResult.err().to_dict()

    book = Book.query.get(isbn)
    if not book:
        return DataResult.err().to_dict()

    book.book_name = data.get('bookName', book.book_name)
    book.author = data.get('author', book.author)
    book.press = data.get('press', book.press)
    book.class_name = data.get('className', book.class_name)

    try:
        db.session.commit()
        return DataResult.success().to_dict()
    except Exception as e:
        db.session.rollback()
        return DataResult.err().to_dict()

# 删除书籍
@app.route('/book', methods=['DELETE'])
def delete_book():
    isbn = request.args.get('isbn')
    if not isbn:
        return DataResult.err().to_dict()

    book = Book.query.get(isbn)
    if not book:
        return DataResult.err().to_dict()

    try:
        db.session.delete(book)
        db.session.commit()
        return DataResult.success().to_dict()
    except Exception as e:
        db.session.rollback()
        return DataResult.err().to_dict()


# 查询书籍借阅信息
@app.route('/book/loan', methods=['GET'])
def book_loan():
    barcode = request.args.get('barcode')
    isbn = request.args.get('isbn')

    if barcode:
        read_books = ReadBook.query.filter_by(barcode=barcode).all()
        if isbn:
            inventory = Inventory.query.filter_by(barcode=barcode).first()
            if inventory and inventory.isbn == isbn:
                data = {'loan': [book.to_dict() for book in read_books],
                        'inventory': inventory.to_dict()}
                return DataResult.success_by_datas(data).to_dict()
            return DataResult.success_by_message("NOT_FOUND").to_dict()
        return DataResult.success_by_datas([[book.to_dict() for book in read_books]]).to_dict()

    if isbn:
        inventories = Inventory.query.filter_by(isbn=isbn).all()
        read_books = []
        inventories_with_loans = []
        for inventory in inventories:
            loans = ReadBook.query.filter_by(barcode=inventory.barcode).all()
            if loans:
                read_books.append(loans[0].to_dict())
                inventories_with_loans.append(inventory.to_dict())
        if read_books:
            data = {'loan': read_books,
                    'inventory': inventories_with_loans}
            return DataResult.success_by_datas(data).to_dict()
        return DataResult.err().to_dict()

    return DataResult.err().to_dict()


# 新增借阅记录
@app.route('/book/loan', methods=['POST'])
def add_loan():
    data = json.loads(request.get_data().decode('utf-8'))
    new_read_book = ReadBook(**data)
    db.session.add(new_read_book)
    db.session.commit()
    return DataResult.success_by_message("新增借阅记录成功")


# 更新借阅记录
@app.route('/book/loan', methods=['PUT'])
def update_loan():
    data = json.loads(request.get_data().decode('utf-8'))
    read_book = ReadBook.query.get(data.get('id'))
    if not read_book:
        return DataResult.err().to_dict()

    for key, value in data.items():
        setattr(read_book, key, value)

    db.session.commit()
    return DataResult.success_by_message("更新借阅信息成功")


# 删除借阅记录（管理员权限）
@app.route('/book/loan', methods=['DELETE'])
def delete_loan():
    # 权限验证逻辑需要实现
    book_id = request.args.get('id', type=int)
    read_book = ReadBook.query.get(book_id)
    if not read_book:
        return DataResult.err().to_dict()

    db.session.delete(read_book)
    db.session.commit()
    return DataResult.success_by_message("删除借阅信息成功")


if __name__ == '__main__':
    app.run()
